<template>
  <div class="container">
    <div v-show="hasSearchText" class="back-icon pointer" @click="clearSearch">
      <Icon name="arrowRight" size="24" style="scale: -1"></Icon>
    </div>
    <div class="input-container" :class="{ 'show-back': hasSearchText }">
      <form action="/search" @submit="onSubmit">
        <InputWrap
          ref="inputRef"
          v-model="inputText"
          :placeholder="$t('nav.search')"
          :errMsg="error"
          :typing-append="true"
          prepend-icon="search"
          append-icon="close"
          @keypress.enter="onKeyDownEnter"
          @update:modelValue="onInput"
          @click:append-icon="() => (inputText = '')"
          @blur="onBlur"
        ></InputWrap>
      </form>
      <transition name="dropdown">
        <div v-show="showDropdown" class="dropdown-container" ref="dropdownRef">
          <div class="">
            <div class="gap-row-10 dropdown-item pointer" @click="onFuzzyClicked(inputText)">
              <Icon name="search" size="14"></Icon>
              <div class="dropdown-text">
                {{ inputText }}
              </div>
            </div>
            <div
              v-for="(fuzzyResult, index) in fuzzyKeywords"
              :key="`dropdown-item-${index}`"
              class="gap-row-10 dropdown-item pointer"
              @click="onFuzzyClicked(fuzzyResult.keyword)"
            >
              <Icon name="search" size="14"></Icon>
              <div class="dropdown-text">
                {{ fuzzyResult.keyword }}
              </div>
            </div>
          </div>
        </div>
      </transition>
    </div>
  </div>
</template>
<script setup>
import { ref, watch } from 'vue'
import { onClickOutside, useDebounceFn } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { useSearchResultStore, useSearchStore } from '@/store/search'
import { parseError, useYup } from '@/plugins/yup'
import InputWrap from '@/components/form/InputWrap.vue'
import API from '@/http'

const yup = useYup()
const schema = yup.string().required().max(64)
const error = ref('')

const searchStore = useSearchStore()
const { updateViewerRouterOriginPath } = searchStore

const searchResultStore = useSearchResultStore()
const { onSearch, clearSearch: $clearSearch } = searchResultStore
const { searchText, hasSearchText } = storeToRefs(searchResultStore)
function clearSearch() {
  inputText.value = ''
  $clearSearch().then(updateViewerRouterOriginPath)
}

const showDropdown = ref(false)
const dropdownRef = ref(null)
onClickOutside(dropdownRef, () => (showDropdown.value = false))

let isEnterUp = false
const inputText = ref(searchText.value)
const onInput = async (value) => {
  isEnterUp = false
  fetchFuzzySearch(value)
}

const fuzzyKeywords = ref([])
const fetchFuzzySearch = useDebounceFn(() => {
  if (isEnterUp) return

  const value = inputText.value
  if (value.length <= 0) {
    fuzzyKeywords.value = []
    return
  }
  showDropdown.value = true
  API.Search.rmdKeyword({ data: { keyword: value } })
    .then((data) => {
      if (value === inputText.value) {
        fuzzyKeywords.value = data
      }
    })
    .catch((e) => {
      console.error(e)
      showDropdown.value = false
    })
}, 500)

function onFuzzyClicked(v) {
  inputText.value = v
  onSearch(v).then(updateViewerRouterOriginPath)
  showDropdown.value = false
  fuzzyKeywords.value = []
}

function onBlur() {
  error.value = ''
}

const validate = () => {
  try {
    schema.validateSync(inputText.value)
    error.value = ''
    return true
  } catch (e) {
    error.value = parseError(e)
    return false
  }
}

const onKeyDownEnter = () => {
  if (!validate()) return
  isEnterUp = true
  showDropdown.value = false
  onSearch(inputText.value).then(updateViewerRouterOriginPath)
}

watch(inputText, (value) => {
  if (value.length <= 0) showDropdown.value = false
})
watch(hasSearchText, (value) => {
  if (!value) inputText.value = ''
})

const inputRef = ref(null)
/**
 * 這裡是為了讓 iPhone | Android 鍵盤可以顯示為搜尋 Enter
 * 所以需要form-submit事件，並將 input 給 blur 掉
 * */
function onSubmit(e) {
  e.preventDefault()
  const inputElement = inputRef.value.$el.querySelector('input')
  inputElement.blur()
}
</script>
<style scoped>
.container {
  position: relative;
  display: flex;
}

.input-container {
  width: 100%;
}

.show-back {
  padding-left: 1.75rem;
}

.back-icon {
  padding-top: 0.75rem;
  display: flex;
  align-items: center;
  justify-content: center;

  position: absolute;
  left: 0;
  z-index: 1;
}

.dropdown-container {
  width: 100%;
  max-height: 22rem;
  overflow-y: auto;

  position: absolute;
  left: 0;
  top: 3.25rem;
  z-index: 100;
  background-color: #333546;
  opacity: 0.95;
  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
  border-radius: 0.5rem;

  transform: translateY(0) scaleY(1);

  .dropdown-item {
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 0.5rem 1rem;

    .dropdown-text {
      display: -webkit-box;
      overflow: hidden;
      text-overflow: ellipsis;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
      line-clamp: 2;

      font-size: 0.875rem;
      font-weight: 400;
      line-height: 1.25rem;
      color: #ffffff;
    }
  }

  .dropdown-item:hover {
    background-color: #181925;
  }
}

.show-icon {
  width: calc(100% - 1.75rem);
}

.dropdown-enter-active,
.dropdown-leave-active {
  transition: transform 0.3s ease;
}

.dropdown-enter-from,
.dropdown-leave-to {
  transform: translateY(-50%) scaleY(0);
}
</style>
